// 处理文章图片
import { uploadImageToAliOS } from './uploadImageToAliOS';
const UPLOAD_ERROR = `${import.meta.env.VITE_OSS_BUCKET_URL}/default/upload-error.png`;

// 处理粘贴文本中的图片
export async function handlePasteImage(html, rtf, filterImage = false) {
  const uploadedImageUrls: string[] = []; // 存储上传后的图片 URL
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, 'text/html');
  const images = doc.querySelectorAll('img');

  // 如果filterImage为true，则移除所有图片 直接返回
  if (filterImage) {
    images.forEach((img) => img.remove());
    return {
      innerHtml: doc.body.innerHTML,
      uploadedImageUrls,
    };
  }

  if (html.indexOf('xmlns:o="urn:schemas-microsoft-com:office:office"') > -1) {
    console.log('内容似乎来自 Word 文档。');

    // 用ftf内的图片来截取
    // 用img来获取，上传的是ftf内的图片资源
    const rtfImageData = extractImageDataFromRtf(rtf);
    const uploadTasks = Array.from(images).map(async (img, index) => {
      const imageHexSource = rtfImageData[index];
      const newSrc = `data:${imageHexSource.type};base64,${_convertHexToBase64(imageHexSource.hex)}`;
      const blob = dataURLtoBlob(newSrc);
      const newUrl = await uploadImageToAliOS(blob);
      img.src = newUrl;
    });
    // 等待所有上传任务完成
    await Promise.all(uploadTasks);
    const innerHtml = doc.body.innerHTML;
    return {
      innerHtml,
      uploadedImageUrls,
    };
  } else {
    console.log('内容似乎来自网络。');

    for (let img of images) {
      console.log('复制上传的img', img);
      // const blob = await fetch(img.src).then((r) => r.blob());
      try {
        const newUrl = await uploadImageToAliOS(img.src);
        img.src = newUrl;
        uploadedImageUrls.push(newUrl); // 添加新 URL 到数组
      } catch (error) {
        console.log('上传图片失败', error);
        img.src = UPLOAD_ERROR;
        img.style.height = '240px';
        img.style.width = '360px';
        console.log('转换图片失败', img);
      }
    }
    const innerHtml = doc.body.innerHTML;
    return {
      innerHtml,
      uploadedImageUrls,
    };
  }
}

// 处理粘贴的文本，只保留图片和文字
export async function handlePasteOnlyImageAndText(html, rtf, filterImage = false) {
  const uploadedImageUrls: string[] = []; // 存储上传后的图片 URL
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, 'text/html');
  const images = doc.querySelectorAll('img');

  // 如果filterImage为true，则移除所有图片 直接返回
  if (filterImage) {
    images.forEach((img) => img.remove());
    return {
      innerHtml: doc.body.innerHTML,
      uploadedImageUrls,
    };
  }

  // 移除所有非图片的HTML标签，只保留纯文本和图片
  doc.body.innerHTML = doc.body.innerHTML.replace(/<(?!img\\b)[^>]*>/gi, '');

  if (html.indexOf('xmlns:o="urn:schemas-microsoft-com:office:office"') > -1) {
    console.log('内容似乎来自 Word 文档。');

    // 用rtf内的图片来截取
    // 用img来获取，上传的是rtf内的图片资源
    const rtfImageData = extractImageDataFromRtf(rtf);
    const uploadTasks = Array.from(images).map(async (img, index) => {
      const imageHexSource = rtfImageData[index];
      const newSrc = `data:${imageHexSource.type};base64,${_convertHexToBase64(imageHexSource.hex)}`;
      const blob = dataURLtoBlob(newSrc);
      const newUrl = await uploadImageToAliOS(blob);
      img.src = newUrl;
    });
    // 等待所有上传任务完成
    await Promise.all(uploadTasks);
    const innerHtml = doc.body.innerHTML;
    return {
      innerHtml,
      uploadedImageUrls,
    };
  } else {
    console.log('内容似乎来自网络。');

    for (let img of images) {
      console.log('复制上传的img', img);
      try {
        const blob = await fetch(img.src).then((r) => r.blob());
        try {
          const newUrl = await uploadImageToAliOS(blob);
          img.src = newUrl;
          uploadedImageUrls.push(newUrl); // 添加新 URL 到数组
        } catch (error) {
          console.log('上传图片失败', error);
        }
      } catch (error) {
        img.src = UPLOAD_ERROR;
        img.style.height = '240px';
        img.style.width = '360px';
        console.log('转换图片失败', img);
      }
    }
    const innerHtml = doc.body.innerHTML;
    console.log('innerHtml', innerHtml);
    return {
      innerHtml,
      uploadedImageUrls,
    };
  }
}

// 图片转化成blob
export function dataURLtoBlob(dataurl) {
  let arr = dataurl.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}

/**
 * 从html代码中匹配返回图片标签img的属性src的值的集合
 * @param htmlData
 * @return Array
 */
export function findAllImgSrcsFromHtml(htmlData: string) {
  let imgReg = /<img.*?(?:>|\/>)/gi; //匹配图片中的img标签
  let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i; // 匹配图片中的src

  let arr = htmlData.match(imgReg); //筛选出所有的img
  if (!arr || (Array.isArray(arr) && !arr.length)) {
    return false;
  }

  let srcArr = [];
  for (let i = 0; i < arr.length; i++) {
    let src: any = arr[i].match(srcReg);
    // 获取图片地址
    srcArr.push(src[1]);
  }

  return srcArr;
}

/**
 * 从rtf内容中匹配返回图片数据的集合
 * @param rtfData
 * @return Array
 */
export function extractImageDataFromRtf(rtfData: string) {
  if (!rtfData) {
    return [];
  }

  const regexPictureHeader = /{\\pict[\s\S]+?({\\\*\\blipuid\s?[\da-fA-F]+)[\s}]*/;
  const regexPicture = new RegExp('(?:(' + regexPictureHeader.source + '))([\\da-fA-F\\s]+)\\}', 'g');
  const images = rtfData.match(regexPicture);
  const result = [];

  if (images) {
    for (const image of images) {
      let imageType: any = false;

      if (image.includes('\\pngblip')) {
        imageType = 'image/png';
      } else if (image.includes('\\jpegblip')) {
        imageType = 'image/jpeg';
      }

      if (imageType) {
        result.push({
          hex: image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, ''),
          type: imageType,
        });
      }
    }
  }

  return result;
}

/**
 * 将html内容中img标签的属性值替换
 * @param htmlData html内容
 * @param imageSrcs html中img的属性src的值的集合
 * @param imagesHexSources rtf中图片数据的集合，与html内容中的img标签对应
 * @param isBase64Data 是否是Base64的图片数据
 * @return String
 */
export function replaceImagesFileSourceWithInlineRepresentation(
  htmlData: string,
  imageSrcs: string | any[],
  imagesHexSources: string | any[],
  isBase64Data = true,
) {
  console.log('imageSrcs.length === imagesHexSources.length', imageSrcs.length, imagesHexSources.length);
  if (imageSrcs.length === imagesHexSources.length) {
    for (let i = 0; i < imageSrcs.length; i++) {
      const newSrc = isBase64Data
        ? `data:${imagesHexSources[i].type};base64,${_convertHexToBase64(imagesHexSources[i].hex)}`
        : imagesHexSources[i];

      htmlData = htmlData.replace(imageSrcs[i], newSrc);
    }
  }

  return htmlData;
}

/**
 * 十六进制转base64
 */
export function _convertHexToBase64(hexString: { match: (arg0: RegExp) => any[] }) {
  return btoa(
    hexString
      .match(/\w{2}/g)
      .map((char) => {
        return String.fromCharCode(parseInt(char, 16));
      })
      .join(''),
  );
}

/**
 * 文本内的图片过滤掉
 */
export function removeImages(htmlString) {
  // 创建一个新的DOM解析器
  var parser = new DOMParser();
  var doc = parser.parseFromString(htmlString, 'text/html');

  // 查找所有的img标签并移除
  var images = doc.querySelectorAll('img');
  images.forEach(function (img) {
    img.parentNode.removeChild(img);
  });

  // 将处理后的文档转换回字符串
  return doc.documentElement.outerHTML;
}

export function extractImagesInfo(htmlString) {
  // 创建一个新的DOM解析器
  const parser = new DOMParser();
  const doc = parser.parseFromString(htmlString, 'text/html');

  // 查找所有的img标签
  const images = doc.querySelectorAll('img');

  // 初始化一个数组来存储图片信息
  const imagesInfo = [];

  // 遍历所有img元素并提取信息
  images.forEach((img) => {
    imagesInfo.push({
      src: img.src,
      width: img.width,
      height: img.height,
    });
  });

  // 返回包含图片信息的数组
  return imagesInfo;
}

// }
export async function extractEditorImagesInfo(imagesList) {
  // 使用Promise.all并行获取所有图片信息
  const imagesInfoPromises = imagesList.map((image) => getImageInfo(image.src));
  return Promise.all(imagesInfoPromises);
}

/**
 * 处理复制内容内的style和其他不必要的属性
 * 保留h1, h2, h3, h4, h5, ul, ol, dl, dt, dd, table, tr, td, th, li, b, strong, span这些标签。
 * 移除audio, canvas, embed, video, script, map, area, frame这些标签。
 * 对于img标签，保留src, width, height属性。
 * 对于a标签，移除所有属性并保留纯文本。
 * 移除其他不常用标签（如em,del,sub等余下的全部抱歉）并仅保留纯文本。
 * @param {string} html - 复制的HTML文本
 * @returns {string} - 清理后的HTML文本
 */
export async function handlePasteHtmlStyle(html: string) {
  console.log('处理前的html:', html);
  // 创建一个新的DOM文档
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, 'text/html');

  // 获取文档中的所有元素
  const elements = doc.body.querySelectorAll('*');

  // 定义需要保留的标签
  const allowedTags = [
    'h1',
    'h2',
    'h3',
    'h4',
    'h5',
    'p',
    'div',
    'ul',
    'ol',
    'li',
    'dl',
    'dt',
    'dd',
    'table',
    'thead',
    'tbody',
    'tfoot',
    'tr',
    'td',
    'th',
    'b',
    'strong',
    'span',
    'br',
  ];
  // 定义需要移除的标签
  const removeTags = ['audio', 'canvas', 'embed', 'video', 'script', 'map', 'area', 'frame'];

  // 遍历每个元素
  elements.forEach((element) => {
    // 移除style属性和class
    element.removeAttribute('style');
    element.removeAttribute('class');

    // 检查是否需要移除整个元素
    if (removeTags.includes(element.tagName.toLowerCase())) {
      element.remove();
      return; // 跳过后续处理
    }

    // 对于img标签，保留src, width, height属性
    if (element.tagName.toLowerCase() === 'img') {
      // 保留src, width, height属性
      const attrsToKeep = ['src', 'width', 'height'];
      for (let i = element.attributes.length - 1; i >= 0; i--) {
        if (!attrsToKeep.includes(element.attributes[i].name)) {
          element.removeAttributeNode(element.attributes[i]);
        }
      }
    } else if (element.tagName.toLowerCase() === 'a') {
      // 如果是带话题或者联系人的a标签，后续根据需求处理
      // 选择所有带有 data-w-e-type="mention" 属性的 a 链接
      // 将a链接转换为纯文本
      const text = element.textContent;
      element.replaceWith(document.createTextNode(text));
    } else if (element.tagName.toLowerCase() === 'h6') {
      // 将h6标签转换为p标签
      element.tagName = 'p';
    }else if (allowedTags.includes(element.tagName.toLowerCase())) {
      // 保留允许的标签
    } else {
      // 移除其他所有属性
      for (let i = element.attributes.length - 1; i >= 0; i--) {
        element.removeAttributeNode(element.attributes[i]);
      }
      // 移除标签，保留纯文本
      const text = document.createTextNode(element.textContent || '');
      element.replaceWith(text);
    }
  });

  // 返回清理后的HTML
  const cleanedHtml = doc.body.innerHTML;
  console.log('处理后的html:', cleanedHtml);
  return cleanedHtml;
}

/**
 * 通过阿里云OSS接口获取图片的宽高信息。
 * @param {string} url - 图片的URL。
 * @returns {Promise<{url: string, width: number | null, height: number | null}>}
 */
export async function getImageInfo(url: string) {
  try {
    const infoUrl = `${url}?x-oss-process=image/info`;
    const response = await fetch(infoUrl);

    if (!response.ok) {
      throw new Error(`Failed to fetch image info for ${url}`);
    }

    const data = await response.json();
    return {
      url,
      width: data.ImageWidth?.value || null,
      height: data.ImageHeight?.value || null,
    };
  } catch (error) {
    console.error(error); // 记录错误
    return { url, width: null, height: null };
  }
}

/**
 * 获取editor内实际存在的话题数量，然后和选中的话题进行比对
 *
 */
export function extractEditorSubjectTalks(editor, topicTalksData: any) {
  const editorTopics = editor.getElemsByType('mention');
  const subjectTalksMap = new Map();
  const atUsersMap = new Map();

  if (editorTopics && editorTopics.length > 0) {
    editorTopics.forEach((item) => {
      if (item.target === '_topic' || item.target === '_at') {
        const urlParams = new URLSearchParams(item.url.split('?')[1]);
        if (item.target === '_topic') {
          const talkName = urlParams.get('name');
          if (talkName && !subjectTalksMap.has(talkName)) {
            subjectTalksMap.set(talkName, { talkName });
          }
        } else if (item.target === '_at') {
          const userId = urlParams.get('userId');
          const name = urlParams.get('name');
          if (userId && !atUsersMap.has(userId)) {
            atUsersMap.set(userId, { userId, name });
          }
        }
      }
    });
  }

  // 将Map转换为数组
  const subjectTalks = Array.from(subjectTalksMap.values());
  const atUsers = Array.from(atUsersMap.values());

  // 过滤标签
  return { subjectTalks, atUsers };
}
